package com.zhc.tools.core.fileimport.strategy;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.zhc.tools.core.fileimport.IDealMultiService;
import com.zhc.tools.core.fileimport.IDealSingleService;
import com.zhc.tools.core.fileimport.IProcessor;
import com.zhc.tools.core.fileimport.IProcessorLog;
import com.zhc.tools.core.fileimport.IProcessorMulti;
import com.zhc.tools.core.fileimport.StrategyContext;
import com.zhc.tools.core.fileimport.domain.ImportFileResultEnum;
import com.zhc.tools.core.fileimport.domain.ImportLogObject;
import com.zhc.tools.core.fileimport.domain.ProcessorMethodEnum;

/**
 * 说明：任务处理器 实现
 * @author zhc
 */
@Service("processor")
public class Processor implements IProcessor, IProcessorMulti {
	
	protected final Log logger = LogFactory.getLog(this.getClass());
	
	@Autowired
	private IProcessorLog iProcessorLog;

	@Override
	public boolean doExecute(StrategyContext strategyContext, List<?> executeData,
			ProcessorMethodEnum processorMethod) {
		boolean flag = false;
		if (ProcessorMethodEnum.preData.equals(processorMethod)) {
			flag = this.preData(strategyContext, executeData);
		} else if (ProcessorMethodEnum.preExecuteData.equals(processorMethod)) {
			flag = this.preExecuteData(strategyContext);
		} else if (ProcessorMethodEnum.executeImport.equals(processorMethod)) {
			flag = this.executeImport(strategyContext, executeData);
		} else if (ProcessorMethodEnum.saveOperateLogMulti.equals(processorMethod)) {
			flag = this.iProcessorLog.saveOperateLogMulti(executeData);
		}
		return flag;
	}

	@SuppressWarnings("unchecked")
	@Override
	public boolean preData(StrategyContext strategyContext, List<?> executeData) {
		boolean result = false;
		if (strategyContext.getUseMulti()) {
			result = ((IDealMultiService) strategyContext.getiDealService()).preData(strategyContext, executeData);
		} else {
			if (executeData != null && executeData.size() > 0) {
        		//数据内容
        		for (int i = 0; i < executeData.size(); i++) {
        			Entry<Integer, Map<Integer, Object>> entry = (Entry<Integer, Map<Integer, Object>>) executeData.get(i);
        			
        			if (entry == null || entry.getKey() == null || entry.getValue() == null || entry.getValue().isEmpty()) {
        				this.logger.error(String.format("Processor#preData param【%s】 is empty", JSON.toJSONString(entry)));
        				continue;
        			}
        			
        			if (entry.getKey().intValue() <= strategyContext.getFileStrategySetting().getSkipLineIndex()) {
        				// 跳过行
        				this.logger.debug(String.format("Processor#preData param【%s】 SkipLineIndex num【%s】", JSON.toJSONString(entry), entry.getKey()));
        				continue;
        			}
        			try {
        				ImportLogObject importLogObject = strategyContext.createImportLogObject(entry);
        				try {
        					if (importLogObject != null) {
        						result = ((IDealSingleService) strategyContext.getiDealService()).preData(importLogObject);
        						if (!result) {
        							this.logger.debug(String.format("Processor#preData line【%s】 dataMap【%s】 error", 
        									entry.getKey(), JSON.toJSONString(entry.getValue())));
        							importLogObject.setStatusByResultEnum(ImportFileResultEnum.MATCH_PARAM_ERROR);
        						}
        					}
        				} catch (Exception e) {
        					importLogObject.setStatusByResultEnum(ImportFileResultEnum.CONV_PARAM_ERROR, e.getMessage());
        					this.logger.error("Processor#preData Exception :", e);
        				}
        			} catch (Exception e1) {
        				this.logger.error("Processor#preData createImportLogObject Exception :", e1);
        			}
        		}
        	}
			
		}
		return result;
	}

	@Override
	public boolean preExecuteData(StrategyContext strategyContext) {
		try {
			List<ImportLogObject> executeDataList = strategyContext.getiDealService().preExecuteData(strategyContext.getImportLogObjects());
			strategyContext.setExecuteDataList(executeDataList);
			return true;
		} catch (Exception e) {
			this.logger.error("Processor#preExecuteData Exception :", e);
			return false;
		}
	}

	@Override
	public boolean executeImport(StrategyContext strategyContext, List<?> executeData) {
		boolean result = false;
		if (strategyContext.getUseMulti()) {
			result = ((IDealMultiService) strategyContext.getiDealService()).execute(strategyContext, executeData);
		} else {
			int success = 0;
			if (executeData != null && executeData.size() > 0) {
				for (int i = 0; i < executeData.size(); i++) {
					try {
						ImportLogObject importLogObject = (ImportLogObject) executeData.get(i);
						result = ((IDealSingleService) strategyContext.getiDealService()).execute(importLogObject);
						this.logger.debug(String.format("Processor#executeImport dataMap【%s】", JSON.toJSONString(importLogObject)));
						if (result) {
							importLogObject.setStatusByResultEnum(ImportFileResultEnum.SUCCESS);
							success++;
						} else {
							this.logger.debug(String.format("Processor#executeImport dataMap【%s】 error", JSON.toJSONString(importLogObject)));
							importLogObject.setStatusByResultEnum(ImportFileResultEnum.BUSINESS_PARAM_ERROR);
						}
					} catch (Exception e) {
						this.logger.error("Processor#executeImport Exception :", e);
					}
				}
			}
			strategyContext.addSuccessCount(success);
		}
		return result;
	}
}
